"""
权限检查依赖
用于验证用户是否有权限访问特定资源
"""
from typing import Optional
from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

from app.api.deps import get_db, get_current_user
from app.models.user import User
from app.models.document import Document
from app.models.note import Note
from app.models.knowledge_base import KnowledgeBase


def check_document_permission(
    doc_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    require_owner: bool = True
) -> Document:
    """
    检查用户是否有权限访问文档
    
    Args:
        doc_id: 文档 ID
        current_user: 当前用户
        db: 数据库会话
        require_owner: 是否要求必须是所有者（False 则管理员也可以）
    
    Returns:
        Document: 文档对象
    
    Raises:
        HTTPException: 如果无权限或文档不存在
    """
    # 查询文档
    document = db.query(Document).filter(Document.id == doc_id).first()
    
    if not document:
        raise HTTPException(status_code=404, detail="文档不存在")
    
    # 检查权限
    is_owner = document.user_id == current_user.id
    is_admin = current_user.role == "admin"
    
    if require_owner:
        # 必须是所有者
        if not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此文档")
    else:
        # 所有者或管理员都可以
        if not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此文档")
    
    return document


def check_note_permission(
    note_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    require_owner: bool = True
) -> Note:
    """
    检查用户是否有权限访问笔记
    
    Args:
        note_id: 笔记 ID
        current_user: 当前用户
        db: 数据库会话
        require_owner: 是否要求必须是所有者
    
    Returns:
        Note: 笔记对象
    
    Raises:
        HTTPException: 如果无权限或笔记不存在
    """
    # 查询笔记
    note = db.query(Note).filter(Note.id == note_id).first()
    
    if not note:
        raise HTTPException(status_code=404, detail="笔记不存在")
    
    # 检查权限
    is_owner = note.user_id == current_user.id
    is_admin = current_user.role == "admin"
    
    if require_owner:
        if not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此笔记")
    else:
        if not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此笔记")
    
    return note


def check_knowledge_base_permission(
    kb_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    require_owner: bool = False
) -> KnowledgeBase:
    """
    检查用户是否有权限访问知识库
    
    Args:
        kb_id: 知识库 ID
        current_user: 当前用户
        db: 数据库会话
        require_owner: 是否要求必须是所有者
    
    Returns:
        KnowledgeBase: 知识库对象
    
    Raises:
        HTTPException: 如果无权限或知识库不存在
    """
    # 查询知识库
    kb = db.query(KnowledgeBase).filter(KnowledgeBase.id == kb_id).first()
    
    if not kb:
        raise HTTPException(status_code=404, detail="知识库不存在")
    
    # 检查权限
    is_owner = kb.user_id == current_user.id
    is_admin = current_user.role == "admin"
    is_public = kb.visibility == "public"
    
    if require_owner:
        # 必须是所有者或管理员
        if not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此知识库")
    else:
        # 公开知识库任何人都可以访问，私有知识库只有所有者和管理员可以访问
        if not is_public and not is_owner and not is_admin:
            raise HTTPException(status_code=403, detail="无权限访问此知识库")
    
    return kb


def require_admin(current_user: User = Depends(get_current_user)) -> User:
    """
    要求用户必须是管理员
    
    Args:
        current_user: 当前用户
    
    Returns:
        User: 当前用户
    
    Raises:
        HTTPException: 如果不是管理员
    """
    if current_user.role != "admin":
        raise HTTPException(
            status_code=403,
            detail="需要管理员权限"
        )
    
    return current_user


def require_manager_or_admin(current_user: User = Depends(get_current_user)) -> User:
    """
    要求用户必须是管理员或经理
    
    Args:
        current_user: 当前用户
    
    Returns:
        User: 当前用户
    
    Raises:
        HTTPException: 如果权限不足
    """
    if current_user.role not in ["admin", "manager"]:
        raise HTTPException(
            status_code=403,
            detail="需要管理员或经理权限"
        )
    
    return current_user

